#include <cstdio>
#include <queue>
#include <memory.h>

using namespace std;

struct Node
{
    int x, y, d, t;
    Node( ) { }
    Node( int _x, int _y, int _d, int _t )
        : x( _x ), y( _y ), d( _d ), t( _t ) { }
};

int a[ 1001 ][ 1001 ][ 4 ], d[ 1001 ][ 1001 ][ 4 ], n, m, mod;
int dir[ 4 ][ 2 ] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };
queue<Node> q;
char map[ 1001 ][ 1001 ];
int x1, y1, x2, y2;

void init( )
{
    int i, j, k;
    char str[ 2 ];
    for ( i = 0; i < n; i++ )
        scanf("%s", map[ i ]);
    while ( !q.empty( ) ) q.pop( );
    memset( a, 0, sizeof( a ) );
    for ( i = 0; i < n; i++ )
        for ( j = 0; j < m; j++ )
            for ( k = 0; k < 4; k++ )
                d[ i ][ j ][ k ] = 10000000;
    scanf("%d%d%d%d%s", &x1, &y1, &x2, &y2, str);
    switch( str[ 0 ] )
    {
        case 'N': q.push( Node( x1, y1, 0, 0 ) ); d[ x1 ][ y1 ][ 0 ] = 0; a[ x1 ][ y1 ][ 0 ] = 1; break;
        case 'E': q.push( Node( x1, y1, 1, 0 ) ); d[ x1 ][ y1 ][ 1 ] = 0; a[ x1 ][ y1 ][ 1 ] = 1; break;
        case 'S': q.push( Node( x1, y1, 2, 0 ) ); d[ x1 ][ y1 ][ 2 ] = 0; a[ x1 ][ y1 ][ 2 ] = 1; break;
        case 'W': q.push( Node( x1, y1, 3, 0 ) ); d[ x1 ][ y1 ][ 3 ] = 0; a[ x1 ][ y1 ][ 3 ] = 1; break;
    }
}

void work( )
{
    Node p;
    int i, ans = 0, t = 10000000;
    while ( !q.empty( ) )
    {
        p = q.front( );
        q.pop( );
        if ( p.t > d[ x2 ][ y2 ][ 0 ] || p.t > d[ x2 ][ y2 ][ 1 ] || p.t > d[ x2 ][ y2 ][ 2 ] || p.t > d[ x2 ][ y2 ][ 3 ] ) break;
        if ( p.t > d[ p.x ][ p.y ][ p.d ] ) continue;
        if ( p.t + 1 == d[ p.x ][ p.y ][ ( p.d + 1 ) % 4 ] )
            a[ p.x ][ p.y ][ ( p.d + 1 ) % 4 ] = ( a[ p.x ][ p.y ][ ( p.d + 1 ) % 4 ] + a[ p.x ][ p.y ][ p.d ] ) % mod;
        if ( p.t + 1 == d[ p.x ][ p.y ][ ( p.d + 3 ) % 4 ] )
            a[ p.x ][ p.y ][ ( p.d + 3 ) % 4 ] = ( a[ p.x ][ p.y ][ ( p.d + 3 ) % 4 ] + a[ p.x ][ p.y ][ p.d ] ) % mod;
        if ( p.t + 1 < d[ p.x ][ p.y ][ ( p.d + 1 ) % 4 ] )
        {
            q.push( Node( p.x, p.y, ( p.d + 1 ) % 4, p.t + 1 ) );
            d[ p.x ][ p.y ][ ( p.d + 1 ) % 4 ] = p.t + 1;
            a[ p.x ][ p.y ][ ( p.d + 1 ) % 4 ] = a[ p.x ][ p.y ][ p.d ];
        }
        if ( p.t + 1 < d[ p.x ][ p.y ][ ( p.d + 3 ) % 4 ] )
        {
            q.push( Node( p.x, p.y, ( p.d + 3 ) % 4, p.t + 1 ) );
            d[ p.x ][ p.y ][ ( p.d + 3 ) % 4 ] = p.t + 1;
            a[ p.x ][ p.y ][ ( p.d + 3 ) % 4 ] = a[ p.x ][ p.y ][ p.d ];
        }
        if ( p.x + dir[ p.d ][ 0 ] >= 0 && p.x + dir[ p.d ][ 0 ] < n && p.y + dir[ p.d ][ 1 ] >= 0 && p.y + dir[ p.d ][ 1 ] < m && map[ p.x + dir[ p.d ][ 0 ] ][ p.y + dir[ p.d ][ 1 ] ] == '.' )
        {
            if ( p.t + 1 == d[ p.x + dir[ p.d ][ 0 ] ][ p.y + dir[ p.d ][ 1 ] ][ p.d ] )
                a[ p.x + dir[ p.d ][ 0 ] ][ p.y + dir[ p.d ][ 1 ] ][ p.d ] = ( a[ p.x + dir[ p.d ][ 0 ] ][ p.y + dir[ p.d ][ 1 ] ][ p.d ] + a[ p.x ][ p.y ][ p.d ] ) % mod;
            if ( p.t + 1 < d[ p.x + dir[ p.d ][ 0 ] ][ p.y + dir[ p.d ][ 1 ] ][ p.d ] )
            {
                a[ p.x + dir[ p.d ][ 0 ] ][ p.y + dir[ p.d ][ 1 ] ][ p.d ] = a[ p.x ][ p.y ][ p.d ];
                d[ p.x + dir[ p.d ][ 0 ] ][ p.y + dir[ p.d ][ 1 ] ][ p.d ] = p.t + 1;
                q.push( Node( p.x + dir[ p.d ][ 0 ], p.y + dir[ p.d ][ 1 ], p.d, p.t + 1 ) );
            }
        }
    }
    for ( i = 0; i < 4; i++ )
        if ( t > d[ x2 ][ y2 ][ i ] )
            t = d[ x2 ][ y2 ][ i ];
    if ( t == 10000000 )
        printf("%d -1\n", mod);
    else
    {
        for ( i = 0; i < 4; i++ )
            if ( d[ x2 ][ y2 ][ i ] == t )
                ans = ( ans + a[ x2 ][ y2 ][ i ] ) % mod;
        printf("%d %d\n", mod, ans);
    }
}

int main( )
{
    int t = 1;
    while ( scanf("%d%d%d", &n, &m, &mod) && mod )
    {
        init( );
        printf("Case %d: ", t++);
        work( );
    }
}
